package org.example.service.processingJudgingResultsImpl;


import cn.hutool.core.codec.Base64;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.log4j.Log4j;
import org.example.Util.HttpClientUtils;
import org.example.Util.hashSet;
import org.example.pojo.Response.JudgeResult;
import org.example.pojo.Submissions;
import org.example.service.handleJudgeResult;
import org.example.service.processingJudgingResults;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Component
@Log4j
public class processingJudgingResultsImpl implements processingJudgingResults {

    private final static String URL="http://192.168.88.140:2358/submissions/batch?tokens=";



    @Autowired
    private handleJudgeResult handleJudgeResult;




    @Override
    @Async("AsyncGetJudge")
    public void GetProcessingJudgingResults(List<Submissions> submissions) {


        for(Submissions submission:submissions){
            try {
                extracted(submission);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }


    }

    private void extracted(Submissions submission) throws InterruptedException {
        //GEt请求，远程URL
        String ResultUrl=URL;

        //获取Tokens,TODO 多用户
        List<String> list = JSONUtil.toList(submission.getJudgmentResult(), String.class);

        List<String> tokens = list.stream()
                .map(s->JSONUtil.toBean(s, Map.class))
                .map(map -> map.get("token").toString())// 使用流处理获取Submissions中的judgmentResult属性
                .filter(Objects::nonNull) // 过滤掉空值
                .collect(Collectors.toList());
        //URL拼接
        ResultUrl = getUrl(ResultUrl, tokens);

        //发送
        try {

            String responseResult = HttpClientUtils.get(ResultUrl); // 发送GET请求获取远程URL的响应结果
            List<JudgeResult> judgeResults = JSONToBean(responseResult);

            hashSet<JudgeResult> set = new hashSet<>(judgeResults);

            //处理正在判题
            List<String> ProcessingTokens = judgeResults.stream()
                    .filter(R -> R.getStatus().getId() == 1 || R.getStatus().getId() == 2)
                    .map(R -> R.getToken())
                    .collect(Collectors.toList());
            log.error(ProcessingTokens);
            //如果为空
            if(! ProcessingTokens.isEmpty()){

                // 优化改进
                for (int i = 0; i <= 3; i++) {
                    log.debug("66666666666666666666666666666666666666");
                    Thread.sleep(1000);
                    String url = getUrl(URL, ProcessingTokens);
                    List<JudgeResult> ProcessJudgeResults = JSONToBean(HttpClientUtils.get(url));
                    ProcessingTokens = ProcessJudgeResults.stream()
                            .filter(R -> R.getStatus().getId() == 1 || R.getStatus().getId() == 2)
                            .map(JudgeResult::getToken)
                            .collect(Collectors.toList());
                    ProcessJudgeResults.stream().forEach(e->{
                        System.out.println(e.getToken()+"::"+e.getStatus().getDescription());
                    });
                    if (ProcessingTokens.isEmpty()) {
                        set.addAll(ProcessJudgeResults);

                        break;
                    }
                }
                if(!ProcessingTokens.isEmpty()){
                    log.error("等待超时！取消任务");
                    set.clear();
                }

            }
            handleJudgeResult.result(submission,new ArrayList<>(set));



        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @NotNull
    private static String getUrl(String ResultUrl, List<String> tokens) {
        StringBuilder urlBuilder = new StringBuilder(ResultUrl);
        tokens.forEach(token-> urlBuilder.append(token).append(","));
        urlBuilder.deleteCharAt(urlBuilder.length()-1).append("&base64_encoded=true");
        ResultUrl = urlBuilder.toString();
        return ResultUrl;
    }

    /**
     * 将字符串序列化为实例对象
     */
     private  List<JudgeResult> JSONToBean(String Json){


         // 增加类型安全和空指针检查
         try {
             // 将Json字符串转换为Map对象
             Map<String, Object> map = JSONUtil.toBean(Json, Map.class);
             // 判断Map中是否包含键"submissions"且对应的值是List类型
             if (map.containsKey("submissions") && map.get("submissions") instanceof List) {
                 // 将Map中键"submissions"对应的值转换为JudgeResult类型的List
                 List<JSONObject> list=   (List<JSONObject>) map.get("submissions");

                 return list.parallelStream()
                     .map(judge -> JSONUtil.toBean(judge, JudgeResult.class))
                     .map(judge -> {
                     // 对judge对象的stdout属性进行Base64解码
                     judge.setStdout(Base64.decodeStr(judge.getStdout()));
                     judge.setStderr(Base64.decodeStr(judge.getStderr()));
                     // 对judge对象的compile_output属性进行Base64解码
                     judge.setCompile_output(Base64.decodeStr(judge.getCompile_output()));
                     // 对judge对象的message属性进行Base64解码
                     judge.setMessage(Base64.decodeStr(judge.getMessage()));
                     // 返回处理后的judge对象
                     return judge;
                 }).collect(Collectors.toList());  // 返回处理后的List
             } else {
                 return Collections.emptyList(); // 返回空列表以避免空指针异常
             }
         } catch (Exception e) {
             e.printStackTrace();
             // 异常处理逻辑
             return Collections.emptyList(); // 返回空列表以避免空指针异常
         }




     }




}
